import numpy as np
import matplotlib.pyplot as plt
import cv2
from functions import *
plt.style.use(plt.style.available[5])
3.1. Box Filter
3.1.3. What is the resulting filter if apply the 3 × 3 box filter many times? (Test on grayscale Elaine Image).
elaine = cv2.imread('Elaine.bmp',cv2.IMREAD_GRAYSCALE)
plt.imshow(elaine,cmap='gray')
print(elaine.dtype)
figure = plt.figure(figsize=(19,19))
for i in range(16):
elaine_padded = clip_filter(elaine,1)
elaine = box_filter(elaine_padded,3,1)
figure.add_subplot(4,4,i+1)
plt.imshow(elaine,cmap='gray')
plt.title(f"iteration({i+1})",color='black')
uint8
3.1.4. How does the size of the mask affect blurring and noise reduction? (Test on grayscale Elaine Image).
elaine = cv2.imread('Elaine.bmp',cv2.IMREAD_GRAYSCALE)
figure = plt.figure(figsize=(19,19))
for i in range(12):
# elaine_padded = clip_filter(elaine,3)
elaine = box_filter(elaine)
figure.add_subplot(3,4,i+1)
plt.imshow(elaine,cmap='gray')
plt.title(f"iteration({i+1})",color='black')
3.1.5. Which mask size do you think provides a better tradeoff between blurring and noise reduction for this image?
elaine = cv2.imread('Elaine.bmp',cv2.IMREAD_GRAYSCALE)
figure = plt.figure(figsize=(18,18))
n = 1 # padding size
m = 3 # window size
for i in range(3):
elaine_padded = clip_filter(elaine,n)
elaine = box_filter(elaine_padded,m,n)
figure.add_subplot(3,3,i+1)
plt.imshow(elaine,cmap='gray')
plt.title(f"window size({m}) ",color='black')
n +=1
m +=2
plt.show()
3.1.6. What is the resulting if apply Laplacian mask ([0 -1 0; -1 5 -1;0 -1 0]) many times? (Test output of 3.1.3).
import numpy as np
import matplotlib.pyplot as plt
import cv2
from functions import *
plt.style.use(plt.style.available[5])
elaine = cv2.imread('Elaine.bmp',cv2.IMREAD_GRAYSCALE)
elaine_padded = clip_filter(elaine,2)
box_elaine = box_filter(elaine_padded,5,2)
mask = np.array([0,-1,0,-1,5,-1,0,-1,0])
mask = mask.reshape(3,3)
figure = plt.figure(figsize=(18,18))
for i in range(4):
box_elaine = laplacian_filter(box_elaine,mask)
figure.add_subplot(1,4,i+1)
plt.imshow(box_elaine,cmap='gray')
plt.title(f"iteration({i}) ",color='black')
3.2. Median Filter
3.2.1. Write a program that can, first, add salt-and-pepper noise to an image with a specified noise density. Try different noise density (0.05, 0.1, 0.2, 0.4). Then, perform median filtering with a specified window size. Consider only the median filter with a square shape. For each density, discuss the effect of filtering with different window sizes (3, 5, 7, 9) and experimentally determine the best window size. Note: you can use imnoise and immse functions to generate noisy images and compare the quality of images, respectively. Also, you can ignore the boundary problem by only performing the filtering for the pixels inside the boundary. (Test on grayscale Elaine Image).
import numpy as np
import matplotlib.pyplot as plt
import cv2
from functions import *
plt.style.use(plt.style.available[5])
eliane = cv2.imread('Elaine.bmp',cv2.IMREAD_GRAYSCALE)
figure = plt.figure(figsize=(15,15))
elaine_noisey = salt_pepper(eliane,0.05)
figure.add_subplot(1,4,1)
plt.imshow(elaine_noisey,cmap='gray')
plt.title('0.05')
elaine_noisey = salt_pepper(eliane,0.1)
figure.add_subplot(1,4,2)
plt.imshow(elaine_noisey,cmap='gray')
plt.title('0.1')
elaine_noisey = salt_pepper(eliane,0.2)
figure.add_subplot(1,4,3)
plt.imshow(elaine_noisey,cmap='gray')
plt.title('0.2')
elaine_noisey = salt_pepper(eliane,0.4)
figure.add_subplot(1,4,4)
plt.imshow(elaine_noisey,cmap='gray')
plt.title('0.4')
Text(0.5, 1.0, '0.4')
eliane = cv2.imread('Elaine.bmp',cv2.IMREAD_GRAYSCALE)
elaine_noisey = salt_pepper(eliane,0.2)
elaine_median = median_filter(eliane,windowSize=3)
plt.imshow(elaine_median,cmap='gray')
<matplotlib.image.AxesImage at 0x1d7fe652b00>
elaine = cv2.imread('Elaine.bmp',cv2.IMREAD_GRAYSCALE)
figure = plt.figure(figsize=(18,18))
noise_density = [0.05 , 0.1, 0.2, 0.4]
windowSizes = [3,5,7,9]
for i,nd in enumerate(noise_density):
for j,ws in enumerate(windowSizes):
elaine_noisey = salt_pepper(elaine,nd)
elaine_median = median_filter(eliane,windowSize=ws)
# calculate MSE, for original image cases
mse = mean_square_error(elaine,elaine_median)
print(f'mean_square_error({i,nd}) = {mse}')
figure.add_subplot(4,4,(4*i)+(j+1))
plt.imshow(elaine_median,cmap='gray')
plt.title(f'noise density:{nd}\nwindow size:{ws}')
mean_square_error((0, 0.05)) = 1318.4843 mean_square_error((0, 0.05)) = 2420.4907 mean_square_error((0, 0.05)) = 3532.5902 mean_square_error((0, 0.05)) = 4578.3781 mean_square_error((1, 0.1)) = 5487.9209 mean_square_error((1, 0.1)) = 7140.6039 mean_square_error((1, 0.1)) = 8686.6320 mean_square_error((1, 0.1)) = 10105.6397 mean_square_error((2, 0.2)) = 11786.5115 mean_square_error((2, 0.2)) = 13721.0691 mean_square_error((2, 0.2)) = 15205.5746 mean_square_error((2, 0.2)) = 16359.9473 mean_square_error((3, 0.4)) = 17408.0267 mean_square_error((3, 0.4)) = 18146.7812 mean_square_error((3, 0.4)) = 18561.2295 mean_square_error((3, 0.4)) = 18776.5542
3.2.2. Create a program for adding Gaussian noise with different variance and filtering using average and median filter, respectively. Apply the averaging filter and the median filter to an image with Gaussian noise (with a chosen noise variance). Discuss the effectiveness of each filter on this type of noise. Note: You can use imnoise and immse functions to generate noisy images and compare the quality of images, respectively. (Test on grayscale Elaine Image).
import numpy as np
import cv2
from matplotlib import pyplot as plt
elaine = cv2.imread("Elaine.bmp",cv2.IMREAD_GRAYSCALE)
mean = 0
var = 80
sigma = var ** 0.8
gaussian = np.random.normal(mean, sigma, size=elaine.shape)
noisy_image = np.zeros_like(elaine)
noisy_image = np.add(elaine,gaussian.astype('uint8'))
plt.imshow(noisy_image, cmap='gray')
<matplotlib.image.AxesImage at 0x1d7fcc7feb0>
figure = plt.figure(figsize=(18,18))
window = [3,5,7,9]
for i in range(4):
elaine_gaussin_medain = median_filter(noisy_image,window[i])
print(mean_square_error(elaine,elaine_gaussin_medain))
figure.add_subplot(1,4,i+1)
plt.imshow(elaine_gaussin_medain,cmap='gray')
plt.title(f"windowSize({window[i]})",color='black')
632.2918 709.8487 927.0042 1169.1656
figure = plt.figure(figsize=(18,18))
window = [3,5,7,9]
for i in range(4):
elaine_gaussin_box = box_filter(noisy_image,window[i])
print(mean_square_error(elaine,elaine_gaussin_box))
figure.add_subplot(1,4,i+1)
plt.imshow(elaine_gaussin_box,cmap='gray')
plt.title(f"windowSize({window[i]})",color='black')
1004.6007 977.1495 1079.5323 1225.8927
3.2.3. Design proper filters to simultaneously remove Gaussian and salt & pepper noise. Please detail the steps of the denoising process and specify corresponding parameters. Provide some discussions about the reason why those filters and parameters are chosen.
elaine = cv2.imread("Elaine.bmp" , cv2.IMREAD_GRAYSCALE)
mean = 0
var = 70
sigma = var ** 0.8
gaussian = np.random.normal(mean, sigma, size=elaine.shape)
noisy_image = np.zeros_like(elaine)
noisy_image = np.add(elaine,gaussian.astype('uint8'))
noisy_image2 = salt_pepper(noisy_image,0.3)
elaine1 = median_filter(noisy_image2,windowSize=5)
elaine2 = box_filter(elaine1,windowSize=3)
plt.imshow(elaine2,cmap='gray')
<matplotlib.image.AxesImage at 0x1d7fcbe4bb0>
3.3. Sharpening, Blurring, and Noise Removal
3.3.1. Take blurry and noisy images (shooting in low light is a good way to get both) by your cellphone and try to improve their appearance and legibility. Display and discuss the results before and after improving.
sample = cv2.imread('sample3.jpg',cv2.IMREAD_GRAYSCALE)
figure = plt.figure(figsize=(18,18))
figure.add_subplot(1,2,1)
plt.imshow(sample,cmap='gray')
sample_gaussin = box_filter(sample,windowSize=11)
image2 = sample_gaussin - sample
a = 0.020
image3 = np.multiply(image2,a)
image4 = sample + image3
figure.add_subplot(1,2,2)
plt.imshow(image4,cmap='gray')
<matplotlib.image.AxesImage at 0x1d7fdfbc5b0>
3.4. Edge Detection
3.4.1. These are often used first-order difference filters in x-direction: 𝑎) 1/2 [1 0 −1], 𝑏) 1/6 [ 1 0 −1 1 0 −1 1 0 −1], 𝑐) 1/8 [ 1 0 −1 2 0 −2 1 0 −1 ] Compare and describe the properties of the three filters; In the following discuss the efficiency of filters for edge detection problems. Are these filters suitable for computing the 2-D gradient? (Test on Elaine Lena Image)
import numpy as np
import matplotlib.pyplot as plt
import cv2
from functions import *
plt.style.use(plt.style.available[5])
elaine = cv2.imread('Elaine.bmp',cv2.IMREAD_GRAYSCALE)
mask1 = np.array([1,0,-1])
mask1 = mask1.reshape(1,3)
mask2 = np.array([1,0,-1,1,0,-1,1,0,-1])
mask2 = mask2.reshape(3,3)
mask3 = np.array([1,0,-1,2,0,-2,1,0,-1])
mask3 = mask3.reshape(3,3)
elaine_a , filter_a = weighted_filter(elaine,mask1,(0.5))
elaine_b , filter_b = weighted_filter(elaine,mask2,(1/6))
elaine_c , filter_c = weighted_filter(elaine,mask3,(1/8))
figure = plt.figure(figsize=(12,12))
figure.add_subplot(3,3,1)
plt.imshow(elaine,cmap='gray')
plt.title('original')
figure.add_subplot(3,3,4)
plt.imshow(elaine_a,cmap='gray')
plt.title('elaine_a')
figure.add_subplot(3,3,5)
plt.imshow(elaine_b,cmap='gray')
plt.title('elaine_b')
figure.add_subplot(3,3,6)
plt.imshow(elaine_c,cmap='gray')
plt.title('elaine_c')
figure.add_subplot(3,3,7)
plt.imshow(filter_a,cmap='gray')
plt.title('edge_a')
figure.add_subplot(3,3,8)
plt.imshow(filter_b,cmap='gray')
plt.title('edge_b')
figure.add_subplot(3,3,9)
plt.imshow(filter_c,cmap='gray')
plt.title('edge_c')
Text(0.5, 1.0, 'edge_c')
3.4.2. Robert suggested the filter to compute the 2-D gradient and to detect edges. 𝑎) [ 1 0 0 −1 ], 𝑏) [ 0 1 −1 0 ] First, in which directions do these filters detect edges? Second, compare the quality of this filter with the filter from previous steps. (Test on grayscale Elaine Image).
elaine = cv2.imread('Elaine.bmp',cv2.IMREAD_GRAYSCALE)
mask1 = np.array([1,0,0,-1])
mask1 = mask1.reshape(2,2)
mask2 = np.array([0,1,-1,0])
mask2 = mask2.reshape(2,2)
robert_a , filter_a = weighted_filter(elaine,mask1)
robert_b , filter_b = weighted_filter(elaine,mask2)
# elaine_c = weighted_filter(elaine,mask3,(1/8))
figure = plt.figure(figsize=(12,12))
figure.add_subplot(2,2,1)
plt.imshow(robert_a,cmap='gray')
plt.title('robert_a')
figure.add_subplot(2,2,2)
plt.imshow(robert_b,cmap='gray')
plt.title('robert_b')
figure.add_subplot(2,2,3)
plt.imshow(filter_a,cmap='gray')
plt.title('edge_b')
figure.add_subplot(2,2,4)
plt.imshow(filter_b,cmap='gray')
plt.title('edge_b')
Text(0.5, 1.0, 'edge_b')
3.5. Unsharp Masking
3.5.1. A simple unsharp masking filter has the following form: (1 − 𝛼)𝐼 + 𝛼𝐼′ = 𝐼 + 𝛼(𝐼′ − 𝐼), where 𝛼 ∈ [0, 1] represents the threshold step of strength sharpening and 𝐼′is smoothed version of 𝐼 which obtained using different filter sizes based on the gaussian filter. Compare and discuss the results for different filter sizes (3, 5, 7, 9, 11) and 𝛼 for the grayscale Lena image. What happens if we set 𝛼 very large or small? How to obtain the optimum value? Note: You can use imgaussfilt function for smoothing.
import numpy as np
import matplotlib.pyplot as plt
import cv2
from functions import *
# from skimage import
plt.style.use(plt.style.available[5])
lena = cv2.imread('Lena.bmp',cv2.IMREAD_GRAYSCALE)
plt.imshow(lena,cmap='gray')
figure = plt.figure(figsize=(18,23))
windowSizes = [3,5,7,9,11]
density = [0.02,0.1,0.25,0.5]
for i , ws in enumerate(windowSizes):
for j , nd in enumerate(density):
lena = cv2.imread('Lena.bmp',cv2.IMREAD_GRAYSCALE)
lena_gaussin = box_filter(lena,windowSize=windowSizes[i])
image2 = lena_gaussin - lena
a = density[j]
image3 = np.multiply(image2,a)
image4 = lena + image3
figure.add_subplot(5,4,(4*i)+(j+1))
plt.imshow(image4,cmap='gray')
plt.title(f'widowSize({windowSizes[i]})\ndensity({density[j]})')